package com.idormy.sms.forwarder.service

import android.app.Notification
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.IBinder
import android.service.notification.NotificationListenerService
import android.service.notification.StatusBarNotification
import com.idormy.sms.forwarder.utils.Log
import com.idormy.sms.forwarder.utils.SettingUtils
import com.idormy.sms.forwarder.workers.CallRecordingWorker

/**
 * 基于通知栏的通话录音服务
 * 通过监听系统通知栏中的通话状态来控制录音
 * 支持系统电话、微信、钉钉等通讯应用
 */
class NotificationCallRecordingService : NotificationListenerService() {

    private val TAG = "NotificationCallRecordingService"
    
    // 通话状态
    private var isInCall = false
    private var currentCallPackage: String? = null
    private var callStartTime = 0L
    
    // 支持的应用包名（国内通讯及交友应用）
    private val supportedPackages = setOf(
        // 系统电话
        "com.android.server.telecom",
        "com.android.phone",
        "com.android.incallui",
        "com.samsung.android.incallui",
        "com.huawei.android.incallui",
        "com.miui.incallui",
        "com.coloros.incallui",
        "com.vivo.incallui",
        "com.oppo.incallui",
        "com.oneplus.incallui",
        "com.meizu.incallui",
        "com.smartisanos.incallui",
        "com.samsung.android.dialer",
        
        // 腾讯系
        "com.tencent.mm",                    // 微信
        "com.tencent.mobileqq",              // QQ
        "com.tencent.tim",                   // TIM
        "com.tencent.qqlite",                // QQ轻聊版
        "com.tencent.wework",                // 企业微信
        "com.tencent.karaoke",               // 全民K歌（含通话功能）
        
        // 阿里系
        "com.alibaba.android.rimet",         // 钉钉
        "com.alibaba.mobileim",              // 阿里旺旺
        "com.taobao.taobao",                 // 淘宝（含语音通话）
        "com.eg.android.AlipayGphone",       // 支付宝（含语音通话）
        
        // 字节系
        "com.ss.android.ugc.aweme",          // 抖音（含语音通话）
        "com.ss.android.lark",               // 飞书
        "com.bytedance.ies.ugc.aweme",       // 抖音极速版
        
        // 其他主流通讯应用
        "cn.com.sina.weibo",                 // 微博（含语音通话）
        "com.xingin.xhs",                    // 小红书（含语音通话）
        "com.baidu.haokan",                  // 好看视频（含语音通话）
        "com.baidu.tieba",                   // 百度贴吧（含语音通话）
        
        // 交友/社交应用
        "com.immomo.momo",                   // 陌陌
        "com.sgiggle.production",            // Soul
        "com.p1.mobile.putong",              // 探探
        "com.yueyue.yueyue",                 // 悦悦
        "com.yimu.yimu",                     // 伊对
        "com.zhenai.android",                // 珍爱网
        "com.jiayuan",                       // 世纪佳缘
        "com.baihe",                         // 百合网
        "com.yodo1.android.sketch",          // 他趣
        "com.wemomo.matchmaking",            // 么么交友
        "com.yueyue.yueyue",                 // 附近约会
        "com.laidian.xiu",                   // 爱聊
        "com.yiyuan.yiya",                   // 一线姻缘
        "com.zhenai.android",                // 真爱
        "com.blued.international",           // Blued
        "com.rela.me"                        // 热拉
    )

    override fun onCreate() {
        super.onCreate()
        Log.d(TAG, "服务onCreate")
    }

    override fun onListenerConnected() {
        super.onListenerConnected()
        Log.d(TAG, "通知监听服务已连接")
    }

    override fun onListenerDisconnected() {
        super.onListenerDisconnected()
        Log.d(TAG, "通知监听服务已断开")
        
        // 如果正在录音，停止录音
        if (isInCall) {
            stopRecording()
        }
        
        // 尝试重新绑定
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            requestRebind(ComponentName(this, NotificationListenerService::class.java))
        }
    }

    override fun onNotificationPosted(sbn: StatusBarNotification?) {
        try {
            sbn?.let { notification ->
                val packageName = notification.packageName
                val notificationText = notification.notification?.tickerText?.toString() ?: ""
                val extras = notification.notification.extras
                
                // 检查是否是支持的应用
                if (!supportedPackages.contains(packageName)) {
                    return
                }
                
                // 获取通知标题和内容
                val title = extras?.getString("android.title") ?: ""
                val content = extras?.getString("android.text") ?: ""
                
                Log.d(TAG, "收到通知: package=$packageName, title=$title, content=$content, ticker=$notificationText")
                
                // 判断是否为通话相关通知
                val isCallNotification = isCallNotification(packageName, title, content, notificationText, notification.notification)
                
                if (isCallNotification && !isInCall) {
                    // 通话开始
                    Log.d(TAG, "检测到通话开始: $packageName")
                    startRecording(packageName)
                } else if (!isCallNotification && isInCall && currentCallPackage == packageName) {
                    // 通话结束
                    Log.d(TAG, "检测到通话结束: $packageName")
                    stopRecording()
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "处理通知异常: ${e.message}")
        }
    }

    override fun onNotificationRemoved(sbn: StatusBarNotification?) {
        try {
            sbn?.let { notification ->
                val packageName = notification.packageName
                
                if (supportedPackages.contains(packageName) && isInCall && currentCallPackage == packageName) {
                    // 通话通知被移除，可能是通话结束
                    Log.d(TAG, "通话通知被移除: $packageName")
                    stopRecording()
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "处理通知移除异常: ${e.message}")
        }
    }

    /**
     * 判断是否为通话相关通知
     */
    private fun isCallNotification(packageName: String, title: String, content: String, ticker: String, notification: Notification): Boolean {
        val fullText = "$title $content $ticker".lowercase()
        
        // 系统电话关键词
        val callKeywords = listOf(
            "来电", "去电", "通话中", "正在通话", "拨号", "呼叫",
            "incoming", "outgoing", "calling", "in call", "on call",
            "voice call", "video call", "语音通话", "视频通话",
            "微信语音", "微信视频", "wechat", "dingtalk", "钉钉"
        )
        
        // 检查是否包含通话关键词
        val hasKeywords = callKeywords.any { keyword ->
            fullText.contains(keyword)
        }
        
        if (!hasKeywords) {
            return false
        }
        
        // 额外的验证机制
        
        // 1. 检查通知优先级（通话通知通常是高优先级）
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val channel = notification.channelId
            // 如果有通知渠道，通常是重要通知
            if (!channel.isNullOrEmpty()) {
                Log.d(TAG, "通知有渠道ID: $channel")
            }
        }
        
        // 2. 检查通知标志（通话通知通常有持续标志）
        val flags = notification.flags
        val isOngoing = (flags and Notification.FLAG_ONGOING_EVENT) != 0
        val isNoClear = (flags and Notification.FLAG_NO_CLEAR) != 0
        
        if (isOngoing || isNoClear) {
            Log.d(TAG, "通知是持续性的，flags=$flags")
            return true
        }
        
        // 3. 检查通知类别（Android 7.0+）
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            val category = notification.category
            if (category == Notification.CATEGORY_CALL) {
                Log.d(TAG, "通知类别是通话: $category")
                return true
            }
        }
        
        // 4. 检查通知时间（通话通知通常会持续较长时间）
        val postTime = notification.`when`
        val currentTime = System.currentTimeMillis()
        val age = currentTime - postTime
        if (age < 5000L) { // 通知在5秒内发布，可能是新通话
            Log.d(TAG, "通知是新发布的，age=${age}ms")
            return true
        }
        
        // 如果以上条件都不满足，但有关键词，给予较低置信度
        Log.d(TAG, "有关键词但无其他通话特征，可能误触发: $fullText")
        return false
    }

    /**
     * 开始录音
     */
    private fun startRecording(packageName: String) {
        if (isInCall) {
            Log.w(TAG, "已经在通话录音中")
            return
        }
        
        try {
            Log.d(TAG, "开始通话录音: $packageName")
            isInCall = true
            currentCallPackage = packageName
            callStartTime = System.currentTimeMillis()
            
            // 启动录音工作器
            CallRecordingWorker.startRecording(this, packageName, -1)
            
        } catch (e: Exception) {
            Log.e(TAG, "启动录音失败: ${e.message}")
            isInCall = false
            currentCallPackage = null
            callStartTime = 0L
        }
    }

    /**
     * 停止录音
     */
    private fun stopRecording() {
        if (!isInCall) {
            Log.w(TAG, "不在通话录音中")
            return
        }
        
        try {
            val callDuration = System.currentTimeMillis() - callStartTime
            Log.d(TAG, "停止通话录音, 时长: ${callDuration}ms")
            
            // 停止录音工作器
            CallRecordingWorker.stopRecording(this)
            
        } catch (e: Exception) {
            Log.e(TAG, "停止录音失败: ${e.message}")
        } finally {
            isInCall = false
            currentCallPackage = null
            callStartTime = 0L
        }
    }

    companion object {
        
        fun start(context: Context) {
            if (!SettingUtils.enableNotificationCallRecording) {
                Log.d("NotificationCallRecording", "通知栏通话录音未启用")
                return
            }
            
            val intent = Intent(context, NotificationCallRecordingService::class.java)
            context.startService(intent)
        }

        fun stop(context: Context) {
            val intent = Intent(context, NotificationCallRecordingService::class.java)
            context.stopService(intent)
        }
    }

    override fun onBind(intent: Intent?): IBinder? = null
}